#ifndef __EMULATOR_PRIV_H__
#define __EMULATOR_PRIV_H__

struct machine {

    /*  We store multiple copies of the machine
        state to enable going back in time. */
    #define SNAPSHOT_COUNT (1<<20)
    struct state snapshot[SNAPSHOT_COUNT];
    uint32_t first_snapshot, last_snapshot;
    #define STATE (mmm->snapshot[mmm->last_snapshot])

    #define REFCOUNT_SATURATED 0x7FFF
    struct {
        /*  This array has one element per word of
            physical memory. v contains the actual
            value of the word at some primordial
            point in time. w contains the number
            of times that word has been written since
            v was valid. If w is zero, then v can be
            used directly; otherwise, one needs to
            munge through the historic states. Updates
            to w must be saturating, and decrements
            must preserve the saturated condition. 
            With this simple mechanism, an emulated
            read can require up to SNAPSHOT_COUNT
            real reads, which is slow. We cache in
            addition the current known-good value of
            the memory cell in r, setting the c flag
            to true if the cache is valid. This means
            that the cost scanning through snapshots
            will be properly amortized. */
        int16_t  v;         //primordial value
        int16_t  r;         //recent value;
        uint16_t w : 15;    //write ref count
        bool     c : 1;     //cache is valid?
    } memory[MEMORY_SIZE];

	/*	Some callbacks are defined to make interaction
		with the front-end easier. These must be cleared
		on load, as they will have invalid addresses. */
	struct {
		void (*tty_callback)(uint8_t, void *);
		void *tty_arg;
	} transient;

};

#endif
